package com.hisense.ovcloud.asop.dao;

import com.hisense.ovcloud.asop.config.Constants;
import com.hisense.ovcloud.asop.dto.db.BindDevicesInfoDto;
import com.hisense.ovcloud.asop.dto.req.PublicInfoReq;
import com.hisense.ovcloud.asop.mapper.CustomerDeviceMapper;
import com.mybatisflex.annotation.UseDataSource;
import com.mybatisflex.core.query.QueryWrapper;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;

import static com.hisense.ovcloud.asop.entity.db.def.CustomerDeviceTableDef.CUSTOMER_DEVICE;
import static com.hisense.ovcloud.asop.entity.db.def.DeviceModuleTableDef.DEVICE_MODULE;
import static com.mybatisflex.core.query.QueryMethods.distinct;

@Service
@Slf4j
public class CustomerDeviceDao {
    final
    CustomerDeviceMapper customerDeviceMapper;

    public CustomerDeviceDao(CustomerDeviceMapper customerDeviceMapper) {
        this.customerDeviceMapper = customerDeviceMapper;
    }

    private QueryWrapper createBaseQueryWrapper(){
        return new QueryWrapper()
                .select(CUSTOMER_DEVICE.ALL_COLUMNS, DEVICE_MODULE.ALL_COLUMNS)
                .from(CUSTOMER_DEVICE, DEVICE_MODULE)
                .where(CUSTOMER_DEVICE.DEVICEMODULEID.eq(DEVICE_MODULE.DEVICEMODULEID))
                .orderBy(CUSTOMER_DEVICE.BINDDATE, false);
    }

    private QueryWrapper createBaseQueryWrapper1(){
        return new QueryWrapper()
                .select(distinct(DEVICE_MODULE.WIFIID))
                .from(CUSTOMER_DEVICE, DEVICE_MODULE)
                .where(CUSTOMER_DEVICE.DEVICEMODULEID.eq(DEVICE_MODULE.DEVICEMODULEID))
                .orderBy(CUSTOMER_DEVICE.BINDDATE, false);
    }

    private QueryWrapper createQueryWrapperForBindDevicesInfo(List<String> customerIdList, PublicInfoReq r){
        QueryWrapper q = createBaseQueryWrapper();
        if(!customerIdList.isEmpty()){
            q = q.and(CUSTOMER_DEVICE.CUSTOMERID.in(customerIdList));
        }
        if(StringUtils.isNotEmpty(r.getWifiId()) ){
            q = q.and(DEVICE_MODULE.WIFIID.eq(r.getWifiId()));
        }
        if(StringUtils.isNotEmpty(r.getPuid())){
            q = q.and(DEVICE_MODULE.PUID.eq(r.getPuid()));
        }
        if(StringUtils.isNotEmpty(r.getDeviceId())){
            q = q.and(DEVICE_MODULE.DEVICEID.eq(r.getDeviceId()));
        }

        return q;
    }

    private QueryWrapper queryWrapperForBindDevicesInfo(PublicInfoReq r){
        QueryWrapper q = createBaseQueryWrapper1();
        if(StringUtils.isEmpty(r.getPuid()) && StringUtils.isEmpty(r.getDeviceId())){
            q = q.and(DEVICE_MODULE.WIFIID.eq(Constants.WIFI_ID_CANNOT_BE_FOUND));
        }else{
            if(StringUtils.isNotEmpty(r.getPuid())){
                q = q.and(DEVICE_MODULE.PUID.eq(r.getPuid()));
            }
            if(StringUtils.isNotEmpty(r.getDeviceId())){
                q = q.and(DEVICE_MODULE.DEVICEID.eq(r.getDeviceId()));
            }
        }


        return q;
    }

    public String findWifiIdByPuidOrDeviceId(PublicInfoReq r){
        String wifiId = Constants.WIFI_ID_CANNOT_BE_FOUND;
        if(StringUtils.isEmpty(r.getDeviceId()) && StringUtils.isEmpty(r.getWifiId()) && StringUtils.isEmpty(r.getPuid())){
            return "";
        }
        if(StringUtils.isNotEmpty(r.getWifiId())){
            return r.getWifiId();
        }else if(StringUtils.isNotEmpty(r.getPuid()) || StringUtils.isNotEmpty(r.getDeviceId())){
            List<String> result = selectWifiByDeviceIdOrPuid(r);
            if(!result.isEmpty()){
                wifiId = result.getFirst();
            }
        }

        return wifiId;
    }

    @UseDataSource(Constants.DS.WGDB)
    public List<BindDevicesInfoDto> fetchBindDevicesInfo(List<String> customerIdList, PublicInfoReq r){
        return customerDeviceMapper.selectListByQueryAs(
                createQueryWrapperForBindDevicesInfo(customerIdList, r)
                        .limit((r.getPageNum()-1) * r.getPageSize(), r.getPageSize()),
                BindDevicesInfoDto.class);
    }

    @UseDataSource(Constants.DS.WGDB)
    public List<BindDevicesInfoDto> fetchAllBindDevicesInfo(List<String> customerIdList, PublicInfoReq r){
        return customerDeviceMapper.selectListByQueryAs(
                createQueryWrapperForBindDevicesInfo(customerIdList, r),
                BindDevicesInfoDto.class);
    }

    @UseDataSource(Constants.DS.WGDB)
    public List<String> selectWifiByDeviceIdOrPuid(PublicInfoReq r){
        return customerDeviceMapper.selectListByQueryAs(
                queryWrapperForBindDevicesInfo(r),
                String.class);
    }

    @UseDataSource(Constants.DS.WGDB)
    public long fetchBindDevicesInfoTotal(List<String> customerIdList, PublicInfoReq r) {
        return customerDeviceMapper.selectCountByQuery(
                createQueryWrapperForBindDevicesInfo(customerIdList, r)
        );
    }

    @UseDataSource(Constants.DS.WGDB)
    public List<String> fetchWifiIdViaCustomIds(List<String> customerIdList){
        QueryWrapper q = new QueryWrapper()
                .select(DEVICE_MODULE.WIFIID)
                .from(CUSTOMER_DEVICE, DEVICE_MODULE)
                .where(CUSTOMER_DEVICE.DEVICEMODULEID.eq(DEVICE_MODULE.DEVICEMODULEID));
        if(!customerIdList.isEmpty()){
            q = q.and(CUSTOMER_DEVICE.CUSTOMERID.in(customerIdList));
        }
        return customerDeviceMapper.selectListByQueryAs(
                q,
                String.class);
    }

}
